package com.emeraldparser.util;

import java.util.Map;

import com.google.common.base.Function;
import com.google.common.collect.Maps;

public class Functions2 {

	/**
	 * Returns a function that will only invoke the original function's
	 * {@link Function#apply(Object)} method the first time a particular input
	 * is provided. After the initial call, the resulting output is cached.
	 * 
	 * @param <F>
	 * @param <T>
	 * @param function
	 * @return
	 */
	public static <F, T> Function<F, T> memoized(final Function<? super F, ? extends T> function) {
		final Map<F, T> memoized = Maps.newHashMap();
		
		return new Function<F, T>() {
			
			@Override
			public T apply(F input) {
				T output = memoized.get(input);
				
				if (output == null && !memoized.containsKey(input)) {
					memoized.put(input, output = function.apply(input));
				}
				
				return output;
			}
			
		};
	}

}
